<template>
	<view class="h5-camera-container">
		<!-- H5 摄像头预览区域 -->
		<view class="camera-section">
			<view class="camera-wrapper">
				<!-- H5 视频预览 - 使用原生HTML -->
				<view v-if="showCamera && !capturedImage" class="video-container" v-html="videoHtml"></view>

				<!-- 摄像头启动提示 -->
				<view v-if="showCamera && !cameraReady && !capturedImage" class="camera-loading">
					<view class="loading-content" @click="startVideoPlay">
						<text class="loading-icon">📷</text>
						<text class="loading-text">{{ guideText }}</text>
						<text class="loading-hint">点击启动摄像头</text>
					</view>
				</view>
				
				<!-- 隐藏的 Canvas 用于截图 -->
				<canvas 
					ref="canvasRef"
					class="hidden-canvas"
					:width="canvasWidth"
					:height="canvasHeight"
				></canvas>
				
				<!-- 人脸识别框 -->
				<view v-if="showCamera && !capturedImage" class="face-guide">
					<view class="face-frame">
						<view class="corner corner-tl"></view>
						<view class="corner corner-tr"></view>
						<view class="corner corner-bl"></view>
						<view class="corner corner-br"></view>
					</view>
					<text class="guide-text">{{ guideText }}</text>
				</view>
				
				<!-- 拍照预览 -->
				<view v-if="capturedImage" class="captured-preview">
					<image :src="capturedImage" class="captured-image" mode="aspectFit"></image>
					<view class="preview-overlay">
						<text class="preview-text">照片预览</text>
					</view>
				</view>
			</view>
			
			<!-- 操作按钮区域 -->
			<view class="controls-section">
				<view class="control-buttons">
					<!-- 重新拍照按钮 -->
					<button 
						v-if="capturedImage" 
						class="btn btn-secondary retake-btn"
						@click="retakePhoto"
					>
						<text class="btn-icon">🔄</text>
						<text>重新拍照</text>
					</button>
					
					<!-- 拍照按钮 -->
					<button 
						v-if="!capturedImage && cameraReady" 
						class="btn btn-primary capture-btn"
						:class="{ 'btn-loading': isCapturing }"
						:disabled="isCapturing"
						@click="capturePhoto"
					>
						<text v-if="isCapturing">拍照中...</text>
						<text v-else>
							<text class="btn-icon">📷</text>
							<text>拍照</text>
						</text>
					</button>
					
					<!-- 确认按钮 -->
					<button 
						v-if="capturedImage" 
						class="btn btn-primary confirm-btn"
						:class="{ 'btn-loading': isProcessing }"
						:disabled="isProcessing"
						@click="confirmPhoto"
					>
						<text v-if="isProcessing">处理中...</text>
						<text v-else>
							<text class="btn-icon">✓</text>
							<text>确认使用</text>
						</text>
					</button>
				</view>
				
				<!-- 取消按钮 -->
				<button class="btn btn-text cancel-btn" @click="cancelCapture">
					<text>取消</text>
				</button>
			</view>
		</view>
		
		<!-- 提示信息 -->
		<view class="tips-section">
			<view class="tips-content">
				<text class="tips-title">拍照提示</text>
				<view class="tips-list">
					<text class="tip-item">• 请保持面部在框内</text>
					<text class="tip-item">• 确保光线充足</text>
					<text class="tip-item">• 保持表情自然</text>
					<text class="tip-item">• 避免佩戴口罩或墨镜</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'

// Props
const props = defineProps({
	mode: {
		type: String,
		default: 'register',
		validator: (value) => ['register', 'login', 'test'].includes(value)
	}
})

// Emits
const emit = defineEmits(['success', 'cancel', 'error'])

// 响应式数据
const showCamera = ref(false)
const cameraReady = ref(false)
const capturedImage = ref('')
const isCapturing = ref(false)
const isProcessing = ref(false)
const guideText = ref('正在启动摄像头...')
const videoHtml = ref('')

// Canvas 相关
const canvasWidth = ref(400)
const canvasHeight = ref(300)

// 引用
const videoRef = ref(null)
const canvasRef = ref(null)

// 媒体流
let mediaStream = null

// 生命周期
onMounted(() => {
	// 延迟初始化，确保DOM完全渲染
	setTimeout(() => {
		initH5Camera()
	}, 300)
})

onUnmounted(() => {
	cleanup()
})

// 方法
const initH5Camera = async () => {
	try {
		// 先清理之前的媒体流
		cleanup()

		guideText.value = '正在启动摄像头...'

		// 按照您提供的方案，直接使用简单配置
		mediaStream = await navigator.mediaDevices.getUserMedia({
			video: {
				facingMode: 'user' // 前置摄像头
			}
		})

		console.log('摄像头流获取成功:', mediaStream)

		// 创建原生HTML5 video元素的HTML字符串
		videoHtml.value = `
			<video
				id="h5CameraVideo"
				class="camera-preview"
				autoplay
				muted
				playsinline
				webkit-playsinline
				style="width: 100%; height: 100%; object-fit: cover; background: #000000;"
			></video>
		`

		// 先显示摄像头区域
		showCamera.value = true

		// 等待 DOM 更新
		await nextTick()

		// 延迟一下确保HTML插入完成
		setTimeout(async () => {
			try {
				// 获取动态创建的视频元素
				const videoElement = document.querySelector('#h5CameraVideo')

				if (videoElement && videoElement.play) {
					console.log('找到视频元素，类型:', videoElement.constructor.name)

					// 设置视频源
					videoElement.srcObject = mediaStream

					// 监听视频事件
					videoElement.onloadedmetadata = () => {
						console.log('视频元数据加载完成')
						cameraReady.value = true
						guideText.value = '摄像头已就绪，点击拍照'
					}

					videoElement.onplaying = () => {
						console.log('视频开始播放')
						cameraReady.value = true
						guideText.value = '摄像头已就绪，点击拍照'
					}

					videoElement.onerror = (error) => {
						console.error('视频播放错误:', error)
						guideText.value = '视频播放失败'
					}

					// 播放视频 - 按照您的方案
					await videoElement.play()
					console.log('视频播放成功')

				} else {
					throw new Error('视频元素未找到或不支持play方法')
				}
			} catch (delayError) {
				console.error('延迟初始化失败:', delayError)
				emit('error', '摄像头初始化失败')
			}
		}, 500)

	} catch (error) {
		console.error('H5 摄像头初始化失败:', error)
		let errorMessage = '无法访问摄像头'

		if (error.name === 'NotAllowedError') {
			errorMessage = '摄像头权限被拒绝，请允许访问摄像头'
		} else if (error.name === 'NotFoundError') {
			errorMessage = '未找到摄像头设备'
		} else if (error.name === 'NotSupportedError') {
			errorMessage = '浏览器不支持摄像头功能'
		} else if (error.name === 'NotReadableError') {
			errorMessage = '摄像头被其他应用占用，请关闭其他使用摄像头的程序后重试'
		}

		emit('error', errorMessage)
	}
}

const capturePhoto = async () => {
	if (!cameraReady.value || isCapturing.value) return

	// 按照您的方案获取元素
	const videoElement = document.querySelector('#h5CameraVideo')
	const canvasElement = canvasRef.value

	if (!videoElement || !canvasElement) {
		console.error('视频元素或 Canvas 元素未找到')
		return
	}

	isCapturing.value = true
	guideText.value = '正在拍照...'

	try {
		// 按照您的方案进行拍照
		canvasElement.width = videoElement.videoWidth || 640
		canvasElement.height = videoElement.videoHeight || 480
		canvasElement.getContext('2d').drawImage(videoElement, 0, 0)

		// 转换为 Base64 图片
		const imageDataUrl = canvasElement.toDataURL('image/jpeg', 0.8)

		capturedImage.value = imageDataUrl
		showCamera.value = false
		guideText.value = '拍照完成'

		// 停止摄像头
		if (mediaStream) {
			mediaStream.getTracks().forEach(track => track.stop())
		}

		uni.showToast({
			title: '拍照成功',
			icon: 'success',
			duration: 1000
		})

	} catch (error) {
		console.error('H5 拍照失败:', error)
		uni.showToast({
			title: '拍照失败，请重试',
			icon: 'none',
			duration: 2000
		})
		guideText.value = '拍照失败，请重试'
	} finally {
		isCapturing.value = false
	}
}

const retakePhoto = async () => {
	capturedImage.value = ''
	await initH5Camera()
}

const confirmPhoto = async () => {
	if (!capturedImage.value || isProcessing.value) return
	
	isProcessing.value = true
	
	try {
		// 模拟处理时间
		await new Promise(resolve => setTimeout(resolve, 1000))
		
		// 返回拍照结果
		emit('success', {
			imagePath: capturedImage.value,
			mode: props.mode
		})
		
	} catch (error) {
		console.error('处理照片失败:', error)
		uni.showToast({
			title: '处理失败，请重试',
			icon: 'none',
			duration: 2000
		})
	} finally {
		isProcessing.value = false
	}
}

const cancelCapture = () => {
	cleanup()
	emit('cancel')
}

const startVideoPlay = async () => {
	console.log('尝试手动启动视频播放...')

	// 按照您的方案获取视频元素
	const videoElement = document.querySelector('#h5CameraVideo')

	if (!videoElement) {
		console.error('视频元素未找到')
		return
	}

	if (!mediaStream) {
		console.error('媒体流未找到，重新初始化摄像头')
		await initH5Camera()
		return
	}

	try {
		// 确保视频元素有媒体流
		if (!videoElement.srcObject) {
			videoElement.srcObject = mediaStream
		}

		// 按照您的方案直接播放
		await videoElement.play()
		console.log('手动启动视频播放成功')
		cameraReady.value = true
		guideText.value = '摄像头已就绪，点击拍照'

	} catch (error) {
		console.error('手动启动视频播放失败:', error)
		guideText.value = '视频播放失败，请重试'
	}
}

const cleanup = () => {
	console.log('清理摄像头资源...')

	// 按照您的方案停止视频播放
	const videoElement = document.querySelector('#h5CameraVideo')
	if (videoElement && videoElement.pause) {
		videoElement.pause()
		videoElement.srcObject = null
		videoElement.onloadedmetadata = null
		videoElement.onplaying = null
		videoElement.onerror = null
	}

	// 停止媒体流
	if (mediaStream) {
		mediaStream.getTracks().forEach(track => {
			console.log('停止媒体轨道:', track.kind, track.label)
			track.stop()
		})
		mediaStream = null
	}

	// 重置状态
	showCamera.value = false
	cameraReady.value = false
	capturedImage.value = ''
	guideText.value = '正在启动摄像头...'
	videoHtml.value = ''
}
</script>

<style lang="scss" scoped>
.h5-camera-container {
	height: 100vh;
	background: #000000;
	display: flex;
	flex-direction: column;
}

.camera-section {
	flex: 1;
	display: flex;
	flex-direction: column;
	position: relative;
}

.camera-wrapper {
	flex: 1;
	position: relative;
	overflow: hidden;
}

.camera-preview {
	width: 100%;
	height: 100%;
	object-fit: cover;
	background: #000000;
}

.camera-loading {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: #000000;
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 5;
}

.loading-content {
	text-align: center;
	color: #ffffff;
	cursor: pointer;
	padding: 20px;
}

.loading-icon {
	display: block;
	font-size: 48px;
	margin-bottom: 16px;
}

.loading-text {
	display: block;
	font-size: 16px;
	margin-bottom: 8px;
}

.loading-hint {
	display: block;
	font-size: 14px;
	color: rgba(255, 255, 255, 0.7);
}

.hidden-canvas {
	position: absolute;
	top: -9999px;
	left: -9999px;
	visibility: hidden;
}

.face-guide {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	z-index: 10;
}

.face-frame {
	width: 240px;
	height: 300px;
	position: relative;
	border: 2px solid rgba(255, 255, 255, 0.3);
	border-radius: 120px;
}

.corner {
	position: absolute;
	width: 30px;
	height: 30px;
	border: 3px solid #00ff00;
	
	&.corner-tl {
		top: -3px;
		left: -3px;
		border-right: none;
		border-bottom: none;
		border-radius: 15px 0 0 0;
	}
	
	&.corner-tr {
		top: -3px;
		right: -3px;
		border-left: none;
		border-bottom: none;
		border-radius: 0 15px 0 0;
	}
	
	&.corner-bl {
		bottom: -3px;
		left: -3px;
		border-right: none;
		border-top: none;
		border-radius: 0 0 0 15px;
	}
	
	&.corner-br {
		bottom: -3px;
		right: -3px;
		border-left: none;
		border-top: none;
		border-radius: 0 0 15px 0;
	}
}

.guide-text {
	display: block;
	text-align: center;
	color: #ffffff;
	font-size: 16px;
	margin-top: 20px;
	text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}

.captured-preview {
	width: 100%;
	height: 100%;
	position: relative;
	background: #000000;
	display: flex;
	align-items: center;
	justify-content: center;
}

.captured-image {
	max-width: 100%;
	max-height: 100%;
}

.preview-overlay {
	position: absolute;
	top: 20px;
	left: 50%;
	transform: translateX(-50%);
	background: rgba(0, 0, 0, 0.7);
	padding: 8px 16px;
	border-radius: 20px;
}

.preview-text {
	color: #ffffff;
	font-size: 14px;
}

.controls-section {
	padding: 20px;
	background: rgba(0, 0, 0, 0.8);
}

.control-buttons {
	display: flex;
	justify-content: center;
	gap: 16px;
	margin-bottom: 16px;
}

.btn {
	padding: 12px 24px;
	border-radius: 25px;
	font-size: 16px;
	font-weight: 600;
	border: none;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	transition: all 0.3s ease;
	
	&.btn-primary {
		background: linear-gradient(135deg, #007AFF 0%, #0051D5 100%);
		color: #ffffff;
		box-shadow: 0 4px 12px rgba(0, 122, 255, 0.3);
		
		&:hover {
			transform: translateY(-2px);
			box-shadow: 0 6px 16px rgba(0, 122, 255, 0.4);
		}
	}
	
	&.btn-secondary {
		background: rgba(255, 255, 255, 0.1);
		color: #ffffff;
		border: 1px solid rgba(255, 255, 255, 0.3);
		
		&:hover {
			background: rgba(255, 255, 255, 0.2);
		}
	}
	
	&.btn-text {
		background: transparent;
		color: rgba(255, 255, 255, 0.7);
		
		&:hover {
			color: #ffffff;
		}
	}
	
	&.btn-loading {
		opacity: 0.7;
		pointer-events: none;
	}
	
	&:disabled {
		opacity: 0.5;
		pointer-events: none;
	}
}

.btn-icon {
	font-size: 18px;
}

.capture-btn {
	min-width: 120px;
}

.confirm-btn {
	min-width: 120px;
}

.cancel-btn {
	width: 100%;
	text-align: center;
}

.tips-section {
	background: rgba(0, 0, 0, 0.9);
	padding: 16px 20px;
}

.tips-content {
	max-width: 300px;
	margin: 0 auto;
}

.tips-title {
	display: block;
	color: #ffffff;
	font-size: 16px;
	font-weight: 600;
	margin-bottom: 12px;
	text-align: center;
}

.tips-list {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.tip-item {
	color: rgba(255, 255, 255, 0.8);
	font-size: 14px;
	line-height: 1.4;
}
</style>
